Completed
Pull Request — master (#69)
by Marcelo
34s
created

boilerplate.js ➔ ... ➔ ???   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
c 0
b 0
f 0
nc 1
dl 0
loc 5
rs 9.4285
nop 1
1
import fs from 'fs';
2
import path from 'path';
3
import { all, promisify, reject } from 'bluebird';
4
import {
5
    append,
6
    dropWhile,
7
    equals,
8
    join,
9
    juxt,
10
    last,
11
    map,
12
    merge,
13
    pick,
14
    prop,
15
    replace,
16
    split
17
} from 'ramda';
18
import semver from 'semver';
19
import superagent from 'superagent';
20
import inquirer from 'inquirer';
21
import { emitSuccess } from './input';
22
23
const request = superagent.agent();
24
const createFolder = promisify(fs.mkdir);
25
const createFile = promisify(fs.writeFile);
26
27
/**
28
 * Formats a formatted String
29
 *
30
 * @param {String} source
31
 * @return {String}
32
 */
33
const format = replace(/\n {8}/g, '\n')
34
    & dropWhile(equals('\n'))
35
    & append('\n')
36
    & join('');
37
38
/**
39
 * Generate the answers from the stdin.
40
 *
41
 * @param {IO} io
0 ignored issues
show
Documentation introduced by
The parameter io does not exist. Did you maybe forget to remove this comment?
Loading history...
42
 * @return {Promise}
43
 */
44
function askQuestions() {
45
    return request.get('https://app.rung.com.br/api/categories')
46
        .then(prop('body') & map(({ name, alias: value }) => ({ name, value })))
0 ignored issues
show
Unused Code introduced by
The parameter alias is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Bug introduced by
The variable value seems to be never declared. If this is a global, consider adding a /** global: value */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
47
        .then(categories => [
48
            { name: 'name', message: 'Project name', default: process.cwd() | split('/') | last },
49
            { name: 'version', message: 'Version', default: '1.0.0', validate: semver.valid & Boolean },
50
            { name: 'title', message: 'Title', default: 'Untitled' },
51
            { name: 'description', message: 'Description' },
52
            { name: 'category', type: 'list', message: 'Category', default: 'miscellaneous', choices: categories },
53
            { name: 'license', message: 'license', default: 'MIT' }
54
        ])
55
        .then(inquirer.createPromptModule());
56
}
57
58
/**
59
 * Creates the folder for the boilerplate based on package name. If the folder
60
 * already exists, throw an error
61
 * Queria estar morta
62
 *
63
 * @param {Object} answers
64
 * @return {Promise}
65
 */
66
function createBoilerplateFolder(answers) {
67
    return createFolder(answers.name)
68
        .catch(~reject(new Error(`Unable to create folder ${answers.name}`)))
69
        .return(answers);
70
}
71
72
/**
73
 * Returns an object in the format { filename :: String, content :: String }
74
 * containing meta-informations about the file
75
 *
76
 * @param {Object} answers
77
 * @return {Object}
78
 */
79
function getPackageMetaFile(answers) {
80
    const packageFields = ['name', 'version', 'license', 'category'];
81
    const packageObject = merge(pick(packageFields, answers),
82
        { dependencies: { 'rung-cli': '0.9.4' } });
83
84
    return {
85
        filename: path.join(answers.name, 'package.json'),
86
        content: JSON.stringify(packageObject, null, 2)
87
    };
88
}
89
90
/**
91
 * Content about README.md file
92
 *
93
 * @param {Object} answers
94
 * @return {Object}
95
 */
96
function getReadMeMetaFile(answers) {
97
    const content = format(`
98
        # Rung ─ ${answers.title}
99
100
        # Development
101
102
        - Use \`yarn\` to install the dependencies
103
        - Use \`rung run\` to start the CLI wizard
104
    `);
105
106
    return { filename: path.join(answers.name, 'README.md'), content };
107
}
108
109
/**
110
 * Content about index.js file
111
 *
112
 * @param {Object} answers
113
 * @return {Object}
114
 */
115
function getIndexFile(answers) {
116
    const content = format(`
117
        import { create } from 'rung-sdk';
118
        import { String as Text } from 'rung-cli/dist/types';
119
120
        function render(name) {
121
            return <b>{ _('Hello {{name}}', { name }) }</b>;
122
        }
123
124
        function main(context) {
125
            const { name } = context.params;
126
            return {
127
                alerts: [{
128
                    title: _('Welcome'),
129
                    content: render(name),
130
                    resources: []
131
                }]
132
            };
133
        }
134
135
        const params = {
136
            name: {
137
                description: _('What is your name?'),
138
                type: Text
139
            }
140
        };
141
142
        export default create(main, {
143
            params,
144
            primaryKey: true,
145
            title: _(${JSON.stringify(answers.title)}),
146
            description: _(${JSON.stringify(answers.description)}),
147
            preview: render('Trixie')
148
        });
149
    `);
150
151
    return { filename: path.join(answers.name, 'index.js'), content };
152
}
153
154
/**
155
 * Creates a boilerplate project
156
 *
157
 * @return {Promise}
158
 */
159
export default function boilerplate() {
160
    return askQuestions()
161
        .then(createBoilerplateFolder)
162
        .then(juxt([getPackageMetaFile, getReadMeMetaFile, getIndexFile]))
163
        .then(map(({ filename, content }) => createFile(filename, content)) & all)
164
        .then(~emitSuccess('project generated'));
165
}
166